﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace Homework5
{
   
        [Serializable]
        public class Order
        {
            public static int OrderQuantity = 0;//当前订单量
            public int OrderNum;//订单编号
            public List<OrderItem> OrderItems = new List<OrderItem>();
            public Customer Customer;
            public readonly double TotalPrice = 0;

            public Order() { }
            public Order(Customer customer, List<OrderItem> orderItems)
            {
                OrderNum = OrderQuantity;
                Customer = customer;
                OrderItems = orderItems;
                OrderQuantity += 1;//订单编号直接由订单量决定，确保订单编号不重复
                foreach (OrderItem oi in orderItems)
                    TotalPrice += oi.Price;
            }



            public override bool Equals(object obj)
            {
                var order = obj as Order;
                return order != null &&
                       EqualityComparer<List<OrderItem>>.Default.Equals(OrderItems, order.OrderItems);
            }



            public override string ToString()
            {
                String str1 = "OrderNum:" + OrderNum + " Customer:" + Customer + "\nOrderItems:\n";
                foreach (OrderItem orderItem in OrderItems)
                {
                    str1 += orderItem.ToString();
                }
                str1 += "TotalPrice:" + TotalPrice;
                return str1;
            }

            public override int GetHashCode()
            {
                var hashCode = -996025175;
                hashCode = hashCode * -1521134295 + OrderNum.GetHashCode();
                hashCode = hashCode * -1521134295 + EqualityComparer<List<OrderItem>>.Default.GetHashCode(OrderItems);
                hashCode = hashCode * -1521134295 + EqualityComparer<Customer>.Default.GetHashCode(Customer);
                hashCode = hashCode * -1521134295 + TotalPrice.GetHashCode();
                return hashCode;
            }
        }

        public class Customer
        {
            public string Name;
            public Customer() { }
            public Customer(string name)
            {
                Name = name;
            }
            public override string ToString()
            {
                return Name;
            }
        }

        public class Goods
        {
            public string Name;
            public double UnitPrice;
            public Goods() { }
            public Goods(string name, double price)
            {
                this.Name = name;
                this.UnitPrice = price;
            }
            public override string ToString()
            {
                return Name + " " + UnitPrice + "yuan/kg ";
            }
        }

        [Serializable]
        public class OrderItem
        {
            public Goods OrderGoods { get; set; }
            public int Quantity { get; set; }
            public double Price { get; }

            public OrderItem(Goods goods, int quantity)
            {
                this.OrderGoods = goods;
                this.Quantity = quantity;
                this.Price = this.OrderGoods.UnitPrice * quantity;
            }

            public OrderItem() { }
            public override string ToString()
            {
                return OrderGoods.ToString() + " " + Quantity + "kg ItemPrice:" + Price + "yuan\n";
            }

            public override bool Equals(object obj)
            {
                var item = obj as OrderItem;
                return item != null &&
                       EqualityComparer<Goods>.Default.Equals(OrderGoods, item.OrderGoods) &&
                       Quantity == item.Quantity &&
                       Price == item.Price;
            }

            public override int GetHashCode()
            {
                var hashCode = -1732923583;
                hashCode = hashCode * -1521134295 + EqualityComparer<Goods>.Default.GetHashCode(OrderGoods);
                hashCode = hashCode * -1521134295 + Quantity.GetHashCode();
                hashCode = hashCode * -1521134295 + Price.GetHashCode();
                return hashCode;
            }
        }

        public class OrderService
        {
            public List<Order> Orders = new List<Order>();

            public void AddOrder(Order order)
            {
                Orders.Add(order);
            }

            public Order DeleteOrder(int num)
            {
                if (this.Orders[num] == null)
                {
                    Console.WriteLine("订单不存在");
                    throw new Exception("删除订单失败");
                }

                Order order = this.Orders[num];
                this.Orders.RemoveAt(num);
                return order;
            }

            public void ReviseOrderByClient(int num, Customer client)
            {
                if (Orders[num] != null)
                    Orders[num].Customer = client;
                else
                    throw new Exception("订单不存在,修改失败");
            }


            public Order InquiryOrderByNum(int num)
            {
                if (Orders[num] != null)
                    return Orders[num];
                else throw new Exception("查找的订单不存在");
            }


            public Order InquiryOrderByClientName(string name)
            {
                var orders = Orders
                            .Where(order => order.Customer.Name == name)
                            .OrderBy(order => order.TotalPrice);
                if (orders == null)
                    throw new Exception("没有这样的订单，查询失败");
                return orders.ToList()[0];
            }

            public Order InquiryOrderByGoodsName(string goodsName)
            {
                var ods = Orders.Where(
                   order => order.OrderItems.Exists(OrderItem => OrderItem.OrderGoods.Name == goodsName));
                if (ods == null)
                    throw new Exception("没有这样的订单，查询失败");
                return ods.ToList()[0];
            }

            public void SortOrders()
            {
                Orders.Sort((o1, o2) => o1.OrderNum - o2.OrderNum);
            }

            public void SortByTotalPrice()
            {
                Orders.Sort((o1, o2) => (int)(o1.TotalPrice - o2.TotalPrice));
            }

            public void Export(string path)
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
                using (FileStream fs = new FileStream(path, FileMode.Create))
                {
                    xmlSerializer.Serialize(fs, Orders);
                }
            }

            public List<Order> Import(string path)
            {
                List<Order> ods = new List<Order>();
                using (FileStream fs = new FileStream(path, FileMode.Open))
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
                    ods = (List<Order>)xmlSerializer.Deserialize(fs);
                    Console.WriteLine("\nDeserialized from s.xml");
                    foreach (Order od in ods)
                        Console.WriteLine(od);
                }
                return ods;
            }

        }
        class Program
        {
            static void Main(string[] args)
            {
                OrderService test = new OrderService();
                Goods goods1 = new Goods("apple", 3);
                Goods goods2 = new Goods("pear", 5);
                Goods goods3 = new Goods("peach", 8);
                Customer client1 = new Customer("hyy");
                Customer client2 = new Customer("hww");
                Order order1 = new Order(client1, new List<OrderItem>() { new OrderItem(goods1, 8), new OrderItem(goods2, 3) });
                Order order2 = new Order(client2, new List<OrderItem>() { new OrderItem(goods1, 4), new OrderItem(goods3, 4) });
                string path = "s.xml";


                test.AddOrder(order1);
                test.AddOrder(order2);
                foreach (Order order in test.Orders)
                {
                    Console.WriteLine(order);
                    Console.WriteLine();
                }
                test.Export(path);
                Console.WriteLine("\nSerialized as XML:");
                Console.WriteLine(File.ReadAllText("s.xml"));
                test.Import(path);

                try
                {
                    Console.WriteLine("InquiryOrderByClientName(hyy):");
                    Console.WriteLine(test.InquiryOrderByClientName("hyy"));
                    Console.WriteLine();
                    Console.WriteLine("InquiryOrderByNum(1):");
                    Console.WriteLine(test.InquiryOrderByNum(1));
                    Console.WriteLine();
                    Console.WriteLine("InquiryOrderByGoodsName('pear'):");
                    Console.WriteLine(test.InquiryOrderByGoodsName("pear"));
                    Console.WriteLine();



                    Console.WriteLine("SortByTotalPrice:");
                    test.SortByTotalPrice();
                    foreach (Order order in test.Orders)
                    {
                        Console.WriteLine(order);
                        Console.WriteLine();
                    }
                    Console.WriteLine("SortOrders:");
                    test.SortOrders();
                    foreach (Order order in test.Orders)
                    {
                        Console.WriteLine(order);
                        Console.WriteLine();
                    }

                }
                catch (Exception e)
                {
                    string msg = "";
                    Console.WriteLine(e.Message);
                    if (e.InnerException != null)
                    {
                        msg += "\r\n具体原因：\r\n" + e.InnerException.Message;
                    }
                    Console.WriteLine(msg);

                }


            }
        }
    }

